package rmi;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.util.ArrayList;

import Server.Game;
import Server.Player;
import Server.Server;



public class RMI_NavalBattle_Service extends java.rmi.server.UnicastRemoteObject 
implements RMI_NavalBattle_Interface, Serializable{

    /**
	 * 
	 */
	private static final long serialVersionUID = 6418255246935722108L;
	
	
    ArrayList <RMI_Observer_Interface> observers = new ArrayList<RMI_Observer_Interface>();
    
    ArrayList <ActiveGame> games =new ArrayList<ActiveGame>();
    ArrayList <UserInfo> users = new ArrayList<UserInfo>();
    
    
    public RMI_NavalBattle_Service()throws RemoteException{
    	

    	
    }

   
    public void changeGameState(int index){
        
    	if(games.get(index-1).active==false){
            games.get(index-1).active=true;
        }
        if(games.get(index-1).active==true)
        {
            games.remove(index-1);
        }
    }
    
    public synchronized void updateObservers() throws RemoteException{

    	RMI_Observer_Interface listener;

    	for(int i=0; i<observers.size(); i++){

    		try{
    			listener = observers.get(i);
    			listener.onDataUpdate();
    		}catch (RemoteException ex){
    			ex.printStackTrace();
    			observers.remove(i);
    			i--;
    		}
    	}
    }
    
    public synchronized void updateGames (Server srv){

    	games.clear();

    	for (Game g : srv.getData().getGames()){

    		ActiveGame ag;

    		if (g.getGameState() == Game.STATE_INITIAL)
    			ag = new ActiveGame(false, g.getPlayer1().getUser().getUserName(), 
    					g.getPlayer2().getUser().getUserName());
    		else
    			ag = new ActiveGame(true, g.getPlayer1().getUser().getUserName(), 
    					g.getPlayer2().getUser().getUserName());


    		games.add(ag);

    	}

    	try {
			updateObservers();
		} catch (RemoteException e) {
		}

    }
    
    public synchronized void updateUsers(Server srv){

    	users.clear();

    	System.out.println("update users");
    	
    	for (Player p : srv.getData().getPlayers()){

    		UserInfo user;

    		user = new UserInfo(p.getUser().getUserName(), p.getPlayerState());
    		
    		users.add(user);
    		
    	}
    	
    	try {
			updateObservers();
		} catch (RemoteException e) {
		}


    }
    
    
    @Override
    public String activeGames() throws RemoteException {
        
        String activeGames = "Jogos actuais:\n";
        String concat1 = new String();
        
       for(int i=0;i<games.size();i++)
        {
            boolean getState = games.get(i).active;         
            String concat = activeGames.concat("\nJogo"+ (i+1) +" \nNome: "+ games.get(i).namePlayer1 +"\nNome: "+ games.get(i).namePlayer2);
            if(getState==true){
                concat1 = concat.concat("\nEstado do jogo: A decorrer\n");
            }
            else{
                concat1 = concat.concat("\nEstado do jogo: A preparar os tabuleiros\n");
            }
            activeGames=concat1;
        }
        
        return activeGames;
    }

    public boolean addGame(boolean state,String name1,String name2) throws RemoteException {
                
        ActiveGame newGame = new ActiveGame(state,name1,name2);
        games.add(newGame);
        
        return true;
    }

    @Override
    public synchronized void newObserver(RMI_Observer_Interface obs) throws RemoteException {
       
    	observers.add(obs);
    	obs.onDataUpdate();
        
    }
    
    @Override
    public synchronized void removeObserver(RMI_Observer_Interface obs) throws RemoteException {
       
    	observers.remove(obs);
        
    }
    
    public synchronized void notifyDisconnect() throws RemoteException{


    	while (observers.size()>0){

    		try{
    			observers.get(0).onServerDown();
    		}catch (Exception ex){}
    		
    		observers.remove(0);
    		
    	}

    }


	@Override
	public ArrayList<ActiveGame> getGames() throws RemoteException {
		return games;
	}


	@Override
	public ArrayList<UserInfo> getUsers() throws RemoteException {
		return users;
	}
    
    
}
